home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / ISSUE08 / TASBVLVE / TASBVLVE.ZIP / tasbvlve.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1996-03-12  |  8.5 KB  |  290 lines

  1. unit TASBvlve;
  2. (**************************************************************************
  3. TASBoolValve class
  4. ==================
  5. A VCL which implements a binary state pipe valve.  (Binary state as opposed
  6. to a real valve where the state of the valve is measured as a percentage
  7. of fully open.)
  8.  
  9. Data type TValveState is used to indicate if valve is open (vsOpen)
  10. or shut (vsShut).
  11.  
  12. Author:  Stewart McSporran
  13. E-Mail:  100753.1703@compuserve.com
  14. Date  :  19/6/95
  15. Copyright ⌐1995-96 Ascendant Software
  16.  
  17. Amendments
  18. ----------
  19. 10/3/96  OnChange event added
  20.  
  21. Licence
  22. =======
  23. Since I have picked up many useful freeware components I have decided to
  24. release this one as freeware as a way of saying thanks.
  25.  
  26. I still retain copyright to this product, but you may use it in any application
  27. you write (commercial or otherwise) without payment to me.  If you amend this
  28. component then please leave this comment block in the amended source code.
  29.  
  30. If you do decide to use this component then please drop me a note.  (We all
  31. need our egos massaged from time to time!)
  32.  
  33. Advert
  34. ======
  35. If you have need of a Delphi programmer (teleworking) then please drop me
  36. a line.  Rates are negotiable.
  37.  
  38. 1 year's experience with Delphi.  3 years C++ (Yeuch!).  BSc Computing Science
  39. Co-authorship "Developing Object Oriented Data Structures in C++", McGraw-Hill
  40. Ex Naval Officer.
  41.  
  42. (I'm currently working as a research assistant, but who wants to work for
  43. others when there's the chance of working for yourself?)
  44. **************************************************************************)
  45.  
  46. interface
  47.  
  48. uses
  49.   SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
  50.   Forms, Dialogs;
  51.  
  52. type
  53.   {Possible states of a valve}
  54.   TValveState = (vsOpen, vsShut);
  55.   {Possible orientations of the valve}
  56.   TValveOrientation = ( voHorizontal, voVertical );
  57.  
  58.   {Need an event handler type for the on change event}
  59.   TValveChangeEvent = procedure (Sender : TObject; NewState :TValveState; var AllowChange : boolean) of object;
  60.  
  61.   TASBoolValve = class(TGraphicControl)
  62.   private
  63.     FState : TValveState;    {State of control (open or shut)}
  64.     FPen : TPen;             {Colour of lines}
  65.     FBrush : TBrush;         {Colour of lever}
  66.     FOrientation : TValveOrientation;     {horizontal or vertical component}
  67.     FOnChange : TValveChangeEvent;
  68.     {Property write procedures}
  69.     procedure SetState(val : TValveState);
  70.     procedure SetPen(val : TPen);
  71.     procedure SetBrush(val : TBrush);
  72.     procedure SetOrientation(val : TValveOrientation);
  73.     {Called when pen or brush is changed to redraw object}
  74.     procedure StyleChanged(Sender : TObject);
  75.   protected
  76.     procedure Paint; override;
  77.     procedure Click; override;
  78.     {Add OnChange event - NewState: State valve will enter if user allows change
  79.                           AllowChange: Set to false to stop valve changing}
  80.     procedure Change(Sender : TObject; NewState :TValveState; var AllowChange : boolean); dynamic;
  81.     {Draws the valve actuator lever at the angle specified.
  82.     Angle measured in degrees 0=shut .. 90=open}
  83.     procedure DrawLever( angle : integer);
  84.   public
  85.     constructor Create(AOwner : TComponent); override;
  86.     destructor Destroy; override;
  87.   published
  88.     property Pen : TPen read FPen write SetPen;
  89.     property Brush : TBrush read FBrush write SetBrush;
  90.     property State : TValveState read FState write SetState default vsShut;
  91.     property Orientation : TValveOrientation read FOrientation write SetOrientation;
  92.     property OnClick;
  93.     property OnChange : TValveChangeEvent read FOnChange write FOnChange;
  94.     property ParentShowHint;
  95.     property ShowHint;
  96.     property Visible;
  97.   end;
  98.  
  99. procedure Register;
  100.  
  101. implementation
  102.  
  103. constructor TASBoolValve.Create(AOwner : TComponent);
  104. begin
  105.   inherited Create(AOwner);
  106.   FState := vsShut;
  107.   Width := 24;
  108.   Height := 18;
  109.   FBrush := TBrush.Create;
  110.   FBrush.Style := bsSolid;
  111.   FBrush.Color := clRed;
  112.   FPen := TPen.Create;
  113.   FPen.OnChange := StyleChanged;
  114.   FBrush.OnChange := StyleChanged;
  115. end;
  116.  
  117. destructor TASBoolValve.Destroy;
  118. begin
  119.   FPen.Free;
  120.   FBrush.Free;
  121.   inherited Destroy;
  122. end;
  123.  
  124. procedure TASBoolValve.SetState(val : TValveState);
  125. begin
  126.   if FState <> val then
  127.   begin
  128.     FState := val;
  129.     Refresh;
  130.   end;
  131. end;
  132.  
  133. procedure TASBoolValve.SetPen(val : TPen);
  134. begin
  135.   FPen.Assign(val);
  136. end;
  137.  
  138. procedure TASBoolValve.SetBrush(val : TBrush);
  139. begin
  140.   FBrush.Assign(val);
  141. end;
  142.  
  143. procedure TASBoolValve.SetOrientation(val : TValveOrientation);
  144. begin
  145.   if FOrientation <> val then
  146.   begin
  147.     FOrientation := val;
  148.     {Swap over the width and height, this re-draws the component}
  149.     SetBounds(Left,Top,Height,Width);
  150.   end;
  151. end;
  152.  
  153. {Just re-draw the component}
  154. procedure TASBoolValve.StyleChanged(Sender : TObject);
  155. begin
  156.   Invalidate;
  157. end;
  158.  
  159. {For maximum speed this should really be drawn into a separate canvas and
  160. then copied onto the screen - but this is fast enough.}
  161. procedure TASBoolValve.Paint;
  162. var
  163.   uDim : integer;   {The unit size for the drawing}
  164.   x1, x2, y1, y2 : integer;
  165. begin
  166.   with Canvas do
  167.   begin
  168.     Pen.Assign(FPen);
  169.     Brush.Assign(FBrush);
  170.     if FOrientation = voHorizontal then
  171.     begin
  172.       uDim := Height div 3;
  173.       {Draw basic shape   |><| }
  174.       MoveTo(0,uDim);
  175.       LineTo(0,Height-1);              {|  }
  176.       LineTo(Width-1,uDim);            { / }
  177.       LineTo(Width-1,Height-1);        {  |}
  178.       LineTo(0,uDim);                  { \ }
  179.       {Draw circle in centre}
  180.       x1 := Width div 2 - uDim div 2;
  181.       y1 := uDim + uDim div 2;
  182.       x2 := x1 + uDim;
  183.       y2 := y1 + uDim;
  184.       Ellipse(x1,y1,x2,y2);
  185.       {Now draw lever}
  186.       if FState = vsShut then
  187.         DrawLever(90)
  188.       else
  189.         DrawLever(180);
  190.     end else begin    {orientation = vertical}
  191.       uDim := Width div 3;
  192.       {Draw basic shape   |><| }
  193.       MoveTo(0,0);
  194.       LineTo(Width-uDim,0);              { - }
  195.       LineTo(0,Height-1);                { / }
  196.       LineTo(Width-uDim,Height-1);       { - }
  197.       LineTo(0,0);                       { \ }
  198.       {Draw circle in centre}
  199.       x1 := uDim div 2;
  200.       y1 := Height div 2 - uDim div 2;
  201.       x2 := x1 + uDim;
  202.       y2 := y1 + uDim;
  203.       Ellipse(x1,y1,x2,y2);
  204.       {Now draw lever}
  205.       if FState = vsShut then
  206.         DrawLever(0)
  207.       else
  208.         DrawLever(90);
  209.     end;
  210.   end;
  211. end;
  212.  
  213. (**************************************************************************
  214. TASBoolValve DrawLever method
  215. Draws the valve actuator lever at the angle specified.
  216. Angle measured in degrees 0=shut .. 90=open
  217. **************************************************************************)
  218. procedure TASBoolValve.DrawLever( angle : integer);
  219. var
  220.   rAngle, phi, dx, dy : extended;
  221.   x, y, uDim, p1x, p1y, p2x, p2y : integer;
  222.   cX, cY : integer;
  223. begin
  224.   {convert angle to radians}
  225.   rAngle := angle * Pi / 180.0;
  226.   if FOrientation = voHorizontal then
  227.   begin
  228.     {Calculate unit dimension (as for Paint)}
  229.     uDim := Height div 3;
  230.     {Get position of lever end (model lever as straight line here)}
  231.     cX := Width div 2;     {centre of circle}
  232.     cY := Height - uDim - 1;
  233.   end else begin
  234.     uDim := Width div 3;
  235.     {Get position of lever end (model lever as straight line here)}
  236.     cX := uDim;     {centre of circle}
  237.     cY := Height div 2;
  238.   end;
  239.   x := trunc(cX + 2 * uDim * cos(rAngle));
  240.   y := trunc(2 * uDim - 2 * uDim * sin(rAngle));
  241.   {Now calculate points at edges of lever}
  242.   phi := pi / 2 - rAngle;
  243.   dx := (uDim div 3) * cos(phi);
  244.   dy := (uDim div 3) * sin(phi);
  245.   p1x := round(x + dx);
  246.   p1y := round(y + dy);
  247.   p2x := round(x - dx);
  248.   p2y := round(y - dy);
  249.   {right, let's draw the polygon}
  250.   Canvas.Pen.Color := FBrush.Color;
  251.   Canvas.Polygon([Point(cX,cY),Point(p1x,p1y),Point(p2x,p2y),
  252.                   Point(cX,cY)]);
  253. end;
  254.  
  255. procedure TASBoolValve.Click;
  256. var
  257.   AllowChange : boolean;
  258.   NewState : TValveState;
  259. begin
  260.   if FState = vsOpen then
  261.     NewState := vsShut
  262.   else
  263.     NewState := vsOpen;
  264.   AllowChange := True;
  265.   {Initiate OnChange event}
  266.   Change(Self,NewState,AllowChange);
  267.   {Respond to AllowChange state}
  268.   if AllowChange then
  269.   begin
  270.     FState := NewState;
  271.     Repaint;
  272.   end;
  273.   inherited Click;
  274. end;
  275.  
  276. procedure TASBoolValve.Change(Sender : TObject; NewState :TValveState;
  277.                                      var AllowChange : boolean);
  278. begin
  279.   {Call user's event handler, if it exists}
  280.   if Assigned(FOnChange) then
  281.     FOnChange(Sender,NewState,AllowChange);
  282. end;
  283.  
  284. procedure Register;
  285. begin
  286.   RegisterComponents('Ascendant', [TASBoolValve]);
  287. end;
  288.  
  289. end.
  290.